package org.cloud.common.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.cloud.common.exception.SlothCloudException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 邮件相关工具类
 * 
 * @author wangyuan
 * @since 2017年11月9日
 */
public class EmailUtils {
    
    private static final Logger logger = LoggerFactory.getLogger(EmailUtils.class);

    private static String host = null;
    private static Integer port = null;
    private static String username = null;
    private static String password = null;
    private static String auth = "true";
    private static String protocol = "smtp";
    
    private static final String DEF_TYPE = "text/html;charset=utf-8";
    
    private static Properties properties = new Properties();
    
    private static void initProperties(){
        // 开启debug调试
        properties.setProperty("mail.debug", "false");
        // 发送服务器需要身份验证
        properties.setProperty("mail.smtp.auth", auth);
        // 发送服务器端口，可以不设置，默认是25
        properties.setProperty("mail.smtp.port", String.valueOf(port));
        // 发送邮件协议名称
        properties.setProperty("mail.transport.protocol", protocol);
        // 设置邮件服务器主机名
        properties.setProperty("mail.host", host);
    }
    
    /**
     * 发送邮件
     * 
     * @param from 发送人
     * @param tos 收件人
     * @param ccs 抄送人
     * @param bccs 暗送人
     * @param subject 主题（邮件标题）
     * @param mp 附件
     * @param content 邮件正文，可以为HTML类型
     * @param type 发送的正文的类型，MIME type of this object
     */
    public static void send(String from, List<String> tos, List<String> ccs, List<String> bccs, 
            String subject, Multipart mp, Object content, String type) {
        try {
            if(properties.isEmpty()){
                initProperties();
            }
            
            Session session = newInstance(properties, username, password);
            
            //创建邮件对象
            Message message = new MimeMessage(session);
            
            //发件人
            if(StringUtils.isNotEmpty(from)){
                message.setFrom(new InternetAddress(from));
            } else {
                message.setFrom(new InternetAddress(username));
            }
            
            //多个收件人
            if(CollectionUtils.isEmpty(tos)){
                throw new SlothCloudException("收件人不能为空");
            } else {
                message.setRecipients(RecipientType.TO, InternetAddress.parse(CollectionUtils.collectionToString(tos)));
            }
            
            //抄送人
            if(CollectionUtils.isNotEmpty(ccs)){
                message.setRecipients(RecipientType.CC, InternetAddress.parse(CollectionUtils.collectionToString(ccs)));
            }
            
            //暗送人
            if(CollectionUtils.isNotEmpty(bccs)){
                message.setRecipients(RecipientType.BCC, InternetAddress.parse(CollectionUtils.collectionToString(bccs)));
            }
            
            //设置主题
            message.setSubject(StringUtils.isEmpty(subject) ? "来自维信金科的邮件" : subject);
            
            //设置附件，有附件的时候，正文在附件中，不需要另外设置正文了
            if(mp != null){
                message.setContent(mp);
            } else {
              //设置正文
                if(StringUtils.isEmpty(type)){
                    type = DEF_TYPE;
                }
                message.setContent(content, type);
            }
            
            //发送
            Transport.send(message);
        } catch (Exception e) {
            logger.error("邮件发送失败，原因是：", e);
            throw new SlothCloudException("邮件发送失败", e);
        }
    }
    
    /**
     * 发送邮件
     * 
     * @param tos 收件人
     * @param subject 主题
     * @param content 邮件正文，可以为HTML类型
     */
    public static void send(List<String> tos, String subject, Object content) {
        send(null, tos, null, null, subject, null, content, null);
    }
    
    /**
     * 发送邮件
     * 
     * @param from 发送人
     * @param to 收件人
     * @param cc 抄送人
     * @param bcc 暗送人
     * @param subject 主题（邮件标题）
     * @param mp 附件
     * @param content 邮件正文，可以为HTML类型
     * @param type 发送的正文的类型，MIME type of this object
     */
    public static void send(String from, String to, String cc, String bcc, 
            String subject, Multipart mp, Object content, String type) {
        List<String> tos = null;
        if(StringUtils.isNotEmpty(to)){
            tos = new ArrayList<>();
            tos.add(to);
        }
        
        List<String> ccs = null;
        if(StringUtils.isNotEmpty(cc)){
            ccs = new ArrayList<>();
            ccs.add(cc);
        }
        
        List<String> bccs = null;
        if(StringUtils.isNotEmpty(bcc)){
            bccs = new ArrayList<>();
            bccs.add(bcc);
        }
        
        send(from, tos, ccs, bccs, subject, mp, content, type);
    }
    
    /**
     * 发送邮件
     * 
     * @param from 发送人
     * @param to 收件人
     * @param subject 主题（邮件标题）
     * @param content 邮件正文，可以为HTML类型
     * @param type 发送的正文的类型，MIME type of this object
     */
    public static void send(String from, String to, String subject, Object content, String type) {
        send(from, to, null, null, subject, null, content, type);
    }
    
    /**
     * 发送邮件
     * 
     * @param from 发送人
     * @param to 收件人
     * @param subject 主题（邮件标题）
     * @param content 邮件正文，可以为HTML类型
     */
    public static void send(String from, String to, String subject, Object content) {
        send(from, to, subject, content, null);
    }
    
    /**
     * 发送邮件
     * 
     * @param to 收件人
     * @param subject 主题（邮件标题）
     * @param content 邮件正文，可以为HTML类型
     */
    public static void send(String to, String subject, Object content) {
        send(null, to, subject, content);
    }
    
    public static void send(List<String> tos, List<String> ccs, String subject, Multipart mp) {
        send(null, tos, ccs, null, subject, mp, null, null);
    }

    /**
     * 创建发送邮件的Session
     * @param props
     * @param userName
     * @param password
     * @return
     */
    private static Session newInstance(Properties props, String userName, String password) {
        return Session.getInstance(props, newInstance(userName, password));
    }

    /**
     * 邮件服务器验证信息
     * @param userName
     * @param password
     * @return
     */
    private static Authenticator newInstance(String userName, String password) {
        return new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(userName, password);
            }
        };
    }

    public static void setHost(String host) {
        EmailUtils.host = host;
    }

    public static void setPort(Integer port) {
        EmailUtils.port = port;
    }

    public static void setUsername(String username) {
        EmailUtils.username = username;
    }

    public static void setPassword(String password) {
        EmailUtils.password = password;
    }

    public static void setAuth(String auth) {
        EmailUtils.auth = auth;
    }

    public static void setProtocol(String protocol) {
        EmailUtils.protocol = protocol;
    }
}
